package com.rupertjones.globalcron.domain;

import com.rupertjones.globalcron.domain.audit.Auditable;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Where;
import org.joda.time.DateTimeZone;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>&copy Rupert Jones 2011,2012</p>
 *
 * @author rup
 */
@Entity
@Table(name = "host")
public class Host extends BaseEntity implements Auditable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column(name = "hostname")
    private String hostname;

    @Column(name = "name")
    private String name;

    @Column(name = "enabled")
    private boolean enabled;

    @Column(name = "timezone_id")
    private String timezoneId;

    @OneToMany(mappedBy = "host", orphanRemoval = true)
    @Access(value = AccessType.PROPERTY)
    @Cascade({ org.hibernate.annotations.CascadeType.ALL })
    @Where(clause = "deleted=0")
    private List<JobDescriptor> jobs = new ArrayList<JobDescriptor>();

    @Override
    public void setId(int id) {
        this.id = id;
    }

    @Override
    public int getId() {
        return id;
    }

    public String getTimezoneId() {
        return timezoneId;
    }

    public void setTimezoneId(String timezoneId) {
        this.timezoneId = timezoneId;
    }

    public String getHostname() {
        return hostname;
    }

    public void setHostname(String hostname) {
        this.hostname = hostname;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public List<JobDescriptor> getJobs() {
        return jobs;
    }

    public void setJobs(List<JobDescriptor> jobs) {
        this.jobs = jobs;
    }

    public String getDescription() {
        return name + " (" + hostname + ")";
    }

    @Override
    public String toString() {
        //return getSummary();
        return String.valueOf(getId());
    }

    public DateTimeZone getTimeZone() {
        return DateTimeZone.forID(getTimezoneId());
    }

    public static String getCurrentHost() {
        InetAddress localMachine;
        try {
            localMachine = InetAddress.getLocalHost();
            return localMachine.getHostName();
        } catch (UnknownHostException e) {
            throw new RuntimeException("Could not determine hostname", e);
        }
    }

    public String getSummary() {
        return String.format("[host: %s] [hostname: %s] [enabled: %s]", getName(), getHostname(), isEnabled());
    }

    @Override
    public String toAuditLog() {
        return getSummary();
    }

    @Override
    public AuditLogType getAuditTypeForUpdate() {
        return AuditLogType.EDIT_HOST;
    }

    @Override
    public AuditLogType getAuditTypeForInsert() {
        return AuditLogType.ADD_HOST;
    }
}
